#include <stdio.h>
#include <pthread.h>

#include "censusslave.h"
#include "stream.h"
#include "slave.h"
#include "network.h"

pthread_t threadServe;
int continueServing = 0;
void (*callback)(struct Envelope * received, struct Envelope * send) = 0;

void serve()
{
	struct Socket socket;
	struct Stream * incomingStream = createStream();
	struct Stream * outgoingStream = createStream();
	struct Envelope * envelopeReceived = 0;
	struct Envelope * envelopeToSend = 0;
	
	if(0 == createSocketTCP(&socket, 0))
	{
		if(0 == bindSocket(&socket))
		{
			startCensusSlave(&socket);
			
			while(continueServing)
			{
				if(0 == receiveStream(&socket, incomingStream))
				{
					if(callback)
					{
						envelopeReceived = deserializeEnvelope(incomingStream);
						if(envelopeReceived)
						{
							envelopeToSend = createEnvelope(0, 0, 0);
							callback(envelopeReceived, envelopeToSend);
							destroyEnvelope(envelopeReceived);
							serializeEnvelope(envelopeToSend, outgoingStream);
							destroyEnvelope(envelopeToSend);
						}
					}
					
					if(0 == sendStream(&socket, outgoingStream))
					{
					}
				}
			}
			stopCensusSlave();
		}
	}
	
	destroyEnvelope(envelopeReceived);
	destroyEnvelope(envelopeToSend);
	destroyStream(incomingStream);
	destroyStream(outgoingStream);
}

void startSlave(void (*cb)(struct Envelope * received, struct Envelope * send))
{
	if(cb == 0)
	{
		printf("WARNING: startSlave() received a null pointer. Cannot start the slave.");
	}
	else
	{
		continueServing = 1;
		callback = cb;
		
		pthread_create(&threadServe, 0, (void *)&serve, 0);
	}
}

void stopSlave()
{
	continueServing = 0;
}

